package com.ygqh.baby.controller.mobile;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.foxinmy.weixin4j.payment.PayRequest;
import com.ygqh.baby.ao.AppType;
import com.ygqh.baby.ao.BusinessModule;
import com.ygqh.baby.ao.CodeConstant;
import com.ygqh.baby.ao.CodeType;
import com.ygqh.baby.ao.OrderStatus;
import com.ygqh.baby.ao.PayType;
import com.ygqh.baby.ao.ResponseEntity;
import com.ygqh.baby.po.YgOrder;
import com.ygqh.baby.po.YgUser;
import com.ygqh.baby.service.YgFrameCodeService;
import com.ygqh.baby.service.YgOrderLogService;
import com.ygqh.baby.service.YgOrderPaymentService;
import com.ygqh.baby.service.YgOrderService;
import com.ygqh.baby.service.YgRechargeMemberRecordService;
import com.ygqh.baby.service.YgUserMemberService;
import com.ygqh.baby.service.pay.app.alipay.AlipayAppApi;
import com.ygqh.baby.service.pay.app.weixin.WxAppPayApi;
import com.ygqh.baby.service.pay.app.weixin.WxAppUtils;
import com.ygqh.baby.utils.ExceptionUtil;
import com.ygqh.baby.utils.SessionUtil;
import com.ygqh.baby.utils.WebUtils;

/**
 * 订单
 * 
 * @author guohao
 *
 */
@Controller
@RequestMapping("/app/pay")
public class AppPayController extends BaseController {

	@Autowired
	private YgOrderService orderService;
	@Autowired
	private YgOrderPaymentService orderPaymentService;
	@Autowired
	private YgFrameCodeService ygFrameCodeService;
	@Autowired
	private YgOrderLogService ygOrderLogService;
	@Autowired
	private YgRechargeMemberRecordService ygRechargeMemberRecordService;
	@Autowired
	private YgUserMemberService ygUserMemberService;
	@Autowired
	private WxAppPayApi wxAppPayApi;
	@Autowired
	private AlipayAppApi alipayAppApi;

	/**
	 * 订单 微信统一下单
	 * 
	 * @param userIp
	 * @param code
	 * @param state
	 * @param callback
	 * @param model
	 * @param request
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "wxAppOrderPay")
	@ResponseBody
	public ResponseEntity wxAppOrderPay(@RequestParam(required = true) Long orderId, @RequestParam(required = true) AppType appType, HttpServletRequest request)
			throws IOException {
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("appType", appType);
		paramMap.put("codeType", CodeType.OrderPM);
		String passbackParams = JSON.toJSONString(paramMap);

		YgUser user = SessionUtil.getCurrentUser();
		String ipAddress = WebUtils.getIpAddr(request);
		String[] split = ipAddress.split(",");
		ipAddress = split[0];
		// 记录入参日志
		ygOrderLogService.addOrderLog(orderId, OrderStatus.WaitingPay, user.getUserName(), appType + ";微信支付：");
		// 判断该订单是否已经支付过
		YgOrder ygOrder = orderService.findByOrderId(orderId);
		if (ygOrder != null && !ygOrder.getOrderStatus().equals(OrderStatus.WaitingPay)) {
			return new ResponseEntity("101", "订单状态有误", ygOrder.getOrderStatus());
		}
		try {
			// 生成支付流水
			Long paymentCode = ygFrameCodeService.getFrameCode(CodeType.OrderPM, new Date());

			BigDecimal totalPrice = ygOrder.getTotalPrice();

			PayRequest createPrePay = wxAppPayApi.createPrePay(appType, paymentCode, totalPrice.multiply(new BigDecimal(100)).intValue(), ipAddress,
					WxAppUtils.wxPayNotifyUrl, passbackParams);

			orderPaymentService.addPaymentRecord(BusinessModule.Order, orderId.toString(), totalPrice, paymentCode.toString(), PayType.WeChat, appType,
					createPrePay.getPrepayId(), null, null);
			// createPrePay.setPartnerId(paymentCode.toString());
			System.out.println(JSON.toJSONString(createPrePay));
			return new ResponseEntity("200", "ok", createPrePay);
		} catch (Exception e) {
			ygOrderLogService.addOrderLog(orderId, OrderStatus.WaitingPay, user.getUserName(), appType + "发起微信支付失败" + e.getMessage());
			e.printStackTrace();
			return new ResponseEntity("400", "系统异常", e.getMessage());
		}
	}

	/**
	 * 微信统一下单回调
	 * 
	 * @param request
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "wxPayCallBack")
	public void wxOrderPayCallBack(HttpServletRequest request, HttpServletResponse response) throws IOException {
		response.setHeader("Content-type", "text/html;charset=UTF-8");
		ServletInputStream in = request.getInputStream();
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = in.read(buffer)) != -1) {
			out.write(buffer, 0, len);
		}
		String result = new String(out.toByteArray(), "UTF-8");
		out.close();
		in.close();
		ygOrderLogService.addOrderLog(1l, OrderStatus.WaitingSend, "系统", "微信支付回调，回调数据 【" + result + "】;");

		String res = wxAppPayApi.wxAppPayCallBack(result);

		ygOrderLogService.addOrderLog(1l, OrderStatus.WaitingSend, "系统", "微信支付回调，返回微信数据 【" + res + "】;");
		logger.debug("\n微信支付回调返回结果：\n" + res);
		
		response.getWriter().print(res);
	}

	/**
	 * 订单 支付宝支付
	* @Title: alipayAppOrder 
	*  @param orderId
	*  @param appType
	*  @param request
	*  @return
	*  @throws IOException    入参
	* @return ResponseEntity    返回类型
	* @author （guohao） 
	* @throws
	* @date 2018年3月21日 下午2:39:10 
	* @version V1.0
	 */
	@RequestMapping(value = "alipayAppOrder")
	@ResponseBody
	public ResponseEntity alipayAppOrder(@RequestParam(required = true) Long orderId, @RequestParam(required = true) AppType appType,
			HttpServletRequest request) throws IOException {
		YgUser user = SessionUtil.getCurrentUser();

		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("appType", appType);
		paramMap.put("codeType", CodeType.OrderPM);
		String passbackParams = JSON.toJSONString(paramMap);
		// 记录入参日志
		ygOrderLogService.addOrderLog(orderId, OrderStatus.WaitingPay, user.getUserName(), appType + "-支付宝支付");
		// 判断该订单是否已经支付过
		YgOrder ygOrder = orderService.findByOrderId(orderId);
		if (ygOrder != null && !ygOrder.getOrderStatus().equals(OrderStatus.WaitingPay)) {
			return new ResponseEntity("101", "订单状态有误", ygOrder.getOrderStatus());
		}
		// 生成支付流水
		Long paymentCode = ygFrameCodeService.getFrameCode(CodeType.OrderPM, new Date());
		orderPaymentService.addPaymentRecord(orderId.toString(), ygOrder.getTotalPrice(), paymentCode.toString(), PayType.Alipay, appType);

		String orderInfo = alipayAppApi.alipayTradeAppPay(paymentCode.toString(), ygOrder.getTotalPrice().toString(), passbackParams, appType);
		if (StringUtils.isBlank(orderInfo)) {
			return new ResponseEntity(CodeConstant.Error.getCode(), CodeConstant.Error.getTitle(), passbackParams);
		}
		Map<String, String> map = new HashMap<>();
		map.put("orderInfo", orderInfo);
		return new ResponseEntity(CodeConstant.Success.getCode(), CodeConstant.Success.getTitle(), map);
	}

	/**
	 * 支付宝支付回调
	 * 
	 * @param request
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "alipayCallBack")
	public void alipayOrderCallBack(HttpServletRequest request, HttpServletResponse response) throws IOException {
		response.setHeader("Content-type", "text/html;charset=UTF-8");

		String result = "success";
		try {
			result = alipayAppApi.alipayCallBack(request.getParameterMap());
		} catch (Exception e) {
			result = "failure";
			e.printStackTrace();
		} // 调用SDK验证签名
		response.getWriter().print(result);
	}

	/**
	 * 支付宝充值VIP
	 * @Title: alipayVip 
	 *  @param orderId
	 *  @param appType
	 *  @param request
	 *  @return
	 *  @throws IOException    入参
	 * @return ResponseEntity    返回类型
	 * @author （guohao） 
	 * @throws
	 * @date 2018年3月21日 下午2:39:10 
	 * @version V1.0
	 * @param 
	 * @throws Exception 
	 */
	@RequestMapping(value = "payVip")
	@ResponseBody
	public ResponseEntity alipayVip(@RequestParam(required = true) AppType appType, @RequestParam(required = true) PayType payType, HttpServletRequest request)
			throws Exception {

		if (!PayType.Alipay.equals(payType) && !PayType.WeChat.equals(payType)) {
			return new ResponseEntity(CodeConstant.Error.getCode(), "只支持微信与支付宝支付。", payType);
		}

		YgUser user = SessionUtil.getCurrentUser();
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("appType", appType);
		paramMap.put("userId", user.getId());

		String passbackParams = JSON.toJSONString(paramMap);
		String attach = user.getId() + "-" + CodeType.RechargeMB;
		// 生成支付流水
		Map<String, Object> map = new HashMap<>();

		BigDecimal vipPrice = ygUserMemberService.getVipPrice();
		Long paymentCode = ygFrameCodeService.getFrameCode(CodeType.RechargeMB, new Date());
		if (PayType.Alipay.equals(payType)) {
			String orderInfo = alipayAppApi.alipayTradeAppPay(paymentCode.toString(), vipPrice.toString(), attach, appType);
			if (StringUtils.isBlank(orderInfo)) {
				return new ResponseEntity(CodeConstant.Error.getCode(), CodeConstant.Error.getTitle(), passbackParams);
			}
			map.put("orderInfo", orderInfo);

		} else if (PayType.WeChat.equals(payType)) {
			String ipAddress = WebUtils.getIpAddr(request).split(",")[0];
			PayRequest prePay = wxAppPayApi.createPrePay(appType, paymentCode, vipPrice.multiply(new BigDecimal(100)).intValue(), ipAddress,
					WxAppUtils.wxPayNotifyUrl, passbackParams);
			map.put("prePayInfo", prePay);
		}
		ygRechargeMemberRecordService.addRecord(user.getId(), paymentCode, vipPrice, "Year", payType, appType);
		map.put("paymentCode", paymentCode);
		return new ResponseEntity(CodeConstant.Success.getCode(), CodeConstant.Success.getTitle(), map);
	}

	// ========================================老版本VIP充值=======================================================
	/**
	 *	微信VIP充值 
	 * @param 
	 * @param userIp
	 * @param code
	 * @param state
	 * @param callback
	 * @param model
	 * @param request
	 * @return
	 * @throws IOException
	 */
	public ResponseEntity wxVipPayOld(@RequestParam(required = true) AppType appType, @RequestParam(required = true) String cardIds, Date birthday,
			HttpServletRequest request) throws IOException {

		YgUser user = SessionUtil.getCurrentUser();
		String ipAddress = WebUtils.getIpAddr(request).split(",")[0];

		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("appType", appType);
		paramMap.put("cardIds", cardIds);
		paramMap.put("birthday", birthday);
		paramMap.put("userId", user.getId());
		String passbackParams = JSON.toJSONString(paramMap);

		// 生成支付流水
		BigDecimal vipPrice = ygUserMemberService.getVipPrice();
		Long paymentCode = ygFrameCodeService.getFrameCode(CodeType.RechargeMB, new Date());

		try {
			PayRequest prePay = wxAppPayApi.createPrePay(appType, paymentCode, vipPrice.multiply(new BigDecimal(100)).intValue(), ipAddress,
					WxAppUtils.wxPayNotifyUrl, passbackParams);

			// 充值会员

			ygRechargeMemberRecordService.addRecord(user.getId(), paymentCode, vipPrice, "Year", PayType.WeChat, appType);

			Map<String, Object> map = new HashMap<>();
			map.put("paymentCode", paymentCode);
			map.put("prePayInfo", prePay);
			return new ResponseEntity(CodeConstant.Success.getCode(), CodeConstant.Success.getTitle(), prePay);

		} catch (Exception e) {
			logger.error(appType + " 女王充值执行失败，paymentCode =" + paymentCode + ";" + ExceptionUtil.getExceptionMsg(e));
			e.printStackTrace();
			return new ResponseEntity(CodeConstant.Error.getCode(), CodeConstant.Error.getTitle(), null);
		}
	}

	/**
	 * 支付宝充值VIP
	* @Title: alipayVip 
	*  @param orderId
	*  @param appType
	*  @param request
	*  @return
	*  @throws IOException    入参
	* @return ResponseEntity    返回类型
	* @author （guohao） 
	* @throws
	* @date 2018年3月21日 下午2:39:10 
	* @version V1.0
	 * @param 
	 */
	public ResponseEntity alipayVipOld(@RequestParam(required = true) AppType appType, @RequestParam(required = true) String cardIds, String birthday,
			HttpServletRequest request) throws IOException {
		YgUser user = SessionUtil.getCurrentUser();
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("appType", appType);
		paramMap.put("cardIds", cardIds);
		paramMap.put("birthday", birthday);
		paramMap.put("userId", user.getId());

		String passbackParams = JSON.toJSONString(paramMap);
		String attach = user.getId() + "-" + CodeType.RechargeMB;
		// 生成支付流水

		BigDecimal vipPrice = ygUserMemberService.getVipPrice();
		Long paymentCode = ygFrameCodeService.getFrameCode(CodeType.RechargeMB, new Date());
		ygRechargeMemberRecordService.addRecord(user.getId(), paymentCode, vipPrice, "Year", PayType.Alipay, appType);
		String orderInfo = alipayAppApi.alipayTradeAppPay(paymentCode.toString(), vipPrice.toString(), attach, appType);
		if (StringUtils.isBlank(orderInfo)) {
			return new ResponseEntity(CodeConstant.Error.getCode(), CodeConstant.Error.getTitle(), passbackParams);
		}
		Map<String, Object> map = new HashMap<>();
		map.put("orderInfo", orderInfo);
		map.put("paymentCode", paymentCode);
		return new ResponseEntity(CodeConstant.Success.getCode(), CodeConstant.Success.getTitle(), map);
	}
}
